package com.springBoot.springBootSysCore.handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

import com.springBoot.springBootSysCore.common.config.Global;
import com.springBoot.springBootSysCore.common.mapper.JsonMapper;
import com.springBoot.springBootSysCore.common.utils.IpUitls;
import com.springBoot.springBootSysCore.common.utils.json.JsonUtil;
import com.springBoot.springBootSysCore.common.utils.returnUtil.CodeEnum;
import com.springBoot.springBootSysCore.common.utils.returnUtil.ResultJsonFormat;
import com.springBoot.springBootSysCore.modules.entity.utils.LogUtils;
import com.springBoot.springBootSysCore.modules.shiro.error.KickoutException;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.io.IOException;
import java.util.Map;

@ControllerAdvice  
public class SpringExceptionHandler{  
  /**
   * 只在controller生效 errorController还处理过
     * 全局处理Exception 
     * 错误的情况下返回500 
     * @param ex 
     * @param request
     * @return 
     */  
    @ExceptionHandler(value = {Exception.class})
    public String handleOtherExceptions(final Exception ex, HttpServletRequest request, HttpServletResponse response,Object handler) {
        request.setAttribute("error", ex.getMessage());
        ex.printStackTrace();
        LogUtils.saveLog(request,response, handler, ex, null);

        String ctxPath = request.getContextPath();
        String requestUri = request.getRequestURI(); // 请求的全路径,比如:
        String uri = requestUri.substring(ctxPath.length());// 全路径除去ctxPath
        String tarUri = uri.trim();
        if(IpUitls.isMobileDevice(request.getHeader("user-agent"))
                || "XMLHttpRequest".equals(request.getHeader("X-Requested-With"))
                || tarUri.contains(Global.getConfig("apiPath"))
                ||"http://runapi.showdoc.cc".equals(request.getHeader("Origin"))){
            ResultJsonFormat rj = new  ResultJsonFormat(CodeEnum.ERROR.value());
            rj.setMsg(ex.getClass().getName());
            return renderString(response, rj.convertResultJsonForData());
        }else{
            return "/error/500";
        }
    }
    /**
	 * 参数绑定异常
	 */
	@ExceptionHandler({BindException.class, ConstraintViolationException.class, ValidationException.class,MissingServletRequestParameterException.class})
    public String bindException(HttpServletRequest request, HttpServletResponse response) {
        String ctxPath = request.getContextPath();
        String requestUri = request.getRequestURI(); // 请求的全路径,比如:
        String uri = requestUri.substring(ctxPath.length());// 全路径除去ctxPath
        String tarUri = uri.trim();

        if(IpUitls.isMobileDevice(request.getHeader("user-agent"))
                || "XMLHttpRequest".equals(request.getHeader("X-Requested-With"))
                || tarUri.contains(Global.getConfig("apiPath"))){
            ResultJsonFormat rj = new  ResultJsonFormat(CodeEnum.InvalidParameter.value());
            rj.setMsg("参数错误");
            return renderString(response, rj.convertResultJsonForData());
        }else{
            return "/error/400";
        }
    }

    /**
     * 客户端返回JSON字符串
     * @param response
     * @param object
     * @return
     */
    protected String renderString(HttpServletResponse response, Object object) {
        return renderString(response, JsonMapper.toJsonString(object), "application/json");
    }
    protected String renderString(HttpServletResponse response, String string, String type) {
        try {
            response.reset();
            response.setContentType(type);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.setCharacterEncoding("utf-8");
            response.getWriter().write(string);
            return null;
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 被踢出
     * @return
     */
    @ExceptionHandler({KickoutException.class})
    public String kickoutException() {
        return "/error/kickOut";
    }

	/**
	 * 授权登录异常
	 */
	@ExceptionHandler({AuthenticationException.class})
    public String authenticationException() {
        return "/error/403";
    }
}